/**
 * 统一请求函数
 * 封装wx.request，支持请求拦截、响应拦截和错误处理
 */

const config = require('./config');

// 基础URL，从配置中获取
const BASE_URL = config.getApiBaseUrl();

// 默认超时时间（毫秒），从配置中获取
const TIMEOUT = config.getRequestTimeout();

// 请求队列，用于处理同时存在的多个请求
let requestQueue = [];

/**
 * 请求函数
 * @param {Object} options - 请求配置
 * @param {string} options.url - 请求地址，可以是相对地址或绝对地址
 * @param {string} [options.method='GET'] - 请求方法，GET, POST, PUT, DELETE等
 * @param {Object} [options.data] - 请求参数
 * @param {Object} [options.header] - 请求头
 * @param {boolean} [options.loading=true] - 是否显示加载提示
 * @param {number} [options.timeout] - 超时时间，默认10秒
 * @param {boolean} [options.showError=true] - 是否自动显示错误提示
 * @returns {Promise} - 返回Promise对象
 */
const request = (options) => {
  // 合并默认配置
  options = Object.assign({
    method: 'GET',
    loading: true,
    timeout: TIMEOUT,
    showError: true
  }, options);

  // 构建完整的URL
  let url = options.url;
  if (!url.startsWith('http')) {
    url = BASE_URL + url;
  }

  // 合并默认请求头
  const header = Object.assign({
    'content-type': 'application/json'
  }, options.header);

  // 获取并添加token，如果有的话
  const token = wx.getStorageSync('token');
  if (token) {
    header['Authorization'] = `Bearer ${token}`;
  }
  header['AppId'] = wx.getAccountInfoSync().miniProgram.appId;
  // 若需要显示加载提示
  if (options.loading) {
    wx.showLoading({
      title: '加载中...',
      mask: true
    });
  }

  // 将请求添加到队列
  const requestTask = { url };
  requestQueue.push(requestTask);

  // 调试日志
  if (config.isDebug()) {
    console.log(`[请求] ${options.method} ${url}`, options.data || {});
  }

  return new Promise((resolve, reject) => {
    wx.request({
      url,
      method: options.method,
      data: options.data,
      header,
      timeout: options.timeout,
      success: (res) => {
        // 调试日志
        if (config.isDebug()) {
          console.log(`[响应] ${options.method} ${url}`, res.data);
        }

        // 请求成功，处理响应
        if (res.statusCode >= 200 && res.statusCode < 300) {
          // 服务器返回的数据结构可能有两种格式：
          // 1. {success: true, message: "提示信息", data: {...}} - 旧格式
          // 2. {code: 0, msg: "提示信息", data: {...}} - 新格式，code=0表示成功
          if (res.data) {
            // 业务成功
            resolve(res.data);
          } else {
            // 业务层面的错误
            const error = {
              code: res.data.code || -1,
              message: res.data.msg || res.data.message || '请求失败',
              data: res.data
            };
            
            if (options.showError) {
              wx.showToast({
                title: error.message,
                icon: 'none',
                duration: 2000
              });
            }
            
            reject(error);
          }
        } else {
          // HTTP错误
          const error = {
            code: res.statusCode,
            message: '请求失败，HTTP状态码：' + res.statusCode,
            data: res.data
          };
          
          // 处理401未授权错误，自动重新登录
          if (res.statusCode === 401) {
            // 清除本地存储的token和用户信息
            wx.removeStorageSync('token');
            wx.removeStorageSync('userInfo');
            
            // 获取当前页面路径
            const pages = getCurrentPages();
            const currentPage = pages[pages.length - 1];
            const currentPath = currentPage ? currentPage.route : '';
            
            // 如果当前不在登录页面，则跳转到登录页面
            if (currentPath !== 'pages/user/login') {
              wx.navigateTo({
                url: '/pages/user/login?redirect=' + encodeURIComponent('/' + currentPath)
              });
            }
          } else if (options.showError) {
            wx.showToast({
              title: error.message,
              icon: 'none',
              duration: 2000
            });
          }
          
          reject(error);
        }
      },
      fail: (err) => {
        // 调试日志
        if (config.isDebug()) {
          console.error(`[请求失败] ${options.method} ${url}`, err);
        }

        // 请求失败，网络错误等
        const error = {
          code: -100,
          message: err.errMsg || '网络请求失败',
          data: err
        };
        
        if (options.showError) {
          wx.showToast({
            title: error.message,
            icon: 'none',
            duration: 2000
          });
        }
        
        reject(error);
      },
      complete: () => {
        // 从请求队列中移除
        requestQueue = requestQueue.filter(item => item !== requestTask);
        
        // 如果队列为空，则隐藏加载提示
        if (requestQueue.length === 0 && options.loading) {
          wx.hideLoading();
        }
      }
    });
  });
};

// 快捷请求方法
request.get = (url, data, options = {}) => {
  return request({
    url,
    method: 'GET',
    data,
    ...options
  });
};

request.post = (url, data, options = {}) => {
  return request({
    url,
    method: 'POST',
    data,
    ...options
  });
};

request.put = (url, data, options = {}) => {
  return request({
    url,
    method: 'PUT',
    data,
    ...options
  });
};

request.delete = (url, data, options = {}) => {
  return request({
    url,
    method: 'DELETE',
    data,
    ...options
  });
};

// 导出请求函数
module.exports = request; 